import { ReactNode, useContext } from "react";
import { Dayjs } from "dayjs";
import cs from "classnames";

import { CalendarProps } from ".";
import allLocales from "./locale";
import LocaleContext from "./LocaleContext";

interface MonthCalendarProps extends CalendarProps {
  selectHandler?: (date: Dayjs) => void;
  curMonth: Dayjs;
}

function getAllDays(date: Dayjs) {
  const startDate = date.startOf("month");
  const day = startDate.day();
  const daysInfo: Array<{ date: Dayjs; currentMonth: Boolean }> = new Array(
    6 * 7
  );

  for (let i = 0; i < daysInfo.length; i++) {
    const curDate = startDate.add(i - day, "day");
    daysInfo[i] = {
      date: curDate,
      currentMonth: curDate.month() === date.month(),
    };
  }

  return daysInfo;
}

function renderDays(
  days: Array<{ date: Dayjs; currentMonth: Boolean }>,
  dateRange: MonthCalendarProps["dateRange"],
  dateInnerContent: MonthCalendarProps["dateInnerContent"],
  value: Dayjs,
  selectHandler?: MonthCalendarProps["selectHandler"]
) {
  const rows = [];
  for (let i = 0; i < 6; i++) {
    // week
    const row = [];
    for (let j = 0; j < 7; j++) {
      // day
      const item = days[i * 7 + j];
      row[j] = (
        <div
        key={j}
          className={[
            "calendar-month-body-cell",
            item.currentMonth ? "calendar-month-body-cell-current" : "",
          ].join(" ")}
          onClick={() => selectHandler?.(item.date)}
        >
          {dateRange ? (
            dateRange(item.date)
          ) : (
            <div className="calendar-month-body-cell-date">
              <div
                className={cs(
                  "calendar-month-body-cell-date-value",
                  value.format("YYYY-MM-DD") === item.date.format("YYYY-MM-DD")
                    ? "calendar-month-body-cell-date-selected"
                    : ""
                )}
              >
                {item.date.date()}
              </div>
              <div className="calendar-month-body-cell-date-content">
                {dateInnerContent?.(item.date)}
              </div>
            </div>
          )}
        </div>
      );
    }
    rows.push(row);
  }
  return rows.map((row,i) => (
    <div key={i} className="calendar-month-body-row">{row}</div>
  ));
}

function MonthCalendar(props: MonthCalendarProps) {
  const localeContext = useContext(LocaleContext);
  const CalendarLocale = allLocales[localeContext.locale];

  const { value, dateRange, dateInnerContent, selectHandler, curMonth } = props;

  const weekList = [
    "sunday",
    "monday",
    "tuesday",
    "wednesday",
    "thursday",
    "friday",
    "saturday",
  ];

  const allDays = getAllDays(curMonth);

  return (
    <div className="calendar-month">
      <div className="calendar-month-week-list">
        {weekList.map((week) => (
          <div className="calendar-month-week-list-item" key={week}>
            {
              // week
              CalendarLocale.week[week]
            }
          </div>
        ))}
      </div>
      <div className="calendar-month-body">
        {renderDays(allDays, dateRange, dateInnerContent, value, selectHandler)}
      </div>
    </div>
  );
}

export default MonthCalendar;
